package com_101aiot.gateway.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com._101aiot.redis.core.RedisService;
import com_101aiot.gateway.config.IgnoreUrlsConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.net.URI;
import java.util.List;
import java.util.Map;

/**
 * 白名单路径访问时需要移除JWT请求头
 * Created by macro on 2020/7/24.
 */
@Slf4j
@RequiredArgsConstructor
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration(proxyBeanMethods = false)
public class IgnoreUrlsRemoveJwtFilter implements WebFilter {

    @Autowired
    private IgnoreUrlsConfig ignoreUrlsConfig;

//    @Autowired
//    private RedisTemplate redisTemplate;

    @Resource
    private RedisService redisService;


    /**
     * 验证JWT前置处理
     * 从header或从url获取token，两者都获取不到，就直接return
     *
     * @param exchange exchange
     * @param chain    chain
     * @return Mono<Void>
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();

        // 白名单路径移除JWT请求头
        URI uri = request.getURI();
        List<String> ignoreUrls = ignoreUrlsConfig.getUrls();
        if (ignoreUrls.contains(uri.getPath())) {
            request = exchange.getRequest().mutate().header("Authorization", "").build();
            exchange = exchange.mutate().request(request).build();
            return chain.filter(exchange);
        }

        // token 从header 或者 urlParam获取
        String token;
        String headerToken = request.getHeaders().getFirst("token");
        String urlToken = request.getQueryParams().getFirst("token");
        if (StrUtil.isNotEmpty(headerToken)) {
            token = headerToken;
        } else {
            token = urlToken;
        }
        // redis 查询并返回，存在的话，就获取jwt并存入header 请求头
//        Map obj = (Map) redisTemplate.opsForValue().get("user_token:" + token);
        Map obj = (Map) redisService.get("user_token:" + token);
//        Object obj = redisService.get("user_token:" + token);
//        JSONObject jsonObject = JSONUtil.parseObj(obj);
//        Map map = JSONUtil.toBean(jsonObject, Map.class);
//        Object jwtToken = map.get("jwtToken");
        if (obj != null) {
            exchange.getRequest().mutate().header("Authorization", "Bearer " + obj.get("jwtToken")).build();
            exchange = exchange.mutate().request(request).build();
            return chain.filter(exchange);
        }

        return chain.filter(exchange);
    }
}
